
package com.idealighter.game.games.texaspoker.manager;

import com.alibaba.fastjson.TypeReference;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.inject.Inject;
import com.google.inject.Singleton;

import com.idealighter.game.core.common.Game;
import com.idealighter.game.games.texaspoker.struct.TexapokerRoom;
import com.idealighter.game.prizepool.manager.PlayerPrizePoolMgrScript;
import com.idealighter.game.prizepool.manager.RoomPrizePoolMgrScript;
import com.idealighter.game.prizepool.struct.control.TexaporkerControl;
import com.idealighter.game.prizepool.struct.player.PlayerPrizePool;
import com.idealighter.game.prizepool.struct.room.ControlStrategy;
import com.idealighter.game.prizepool.struct.room.RoomPrizePool;
import com.idealighter.utils.code.RandCodeUtil;

import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * . 德州扑克控制 .
 * 
 * @date 2015年10月17日 下午7:41:31
 */
@Singleton
public class TexapokerControlScript {

  private static final TypeReference<TexaporkerControl> TEXAPOKER_CONTROL_TYPE_REFERENCE =
      new TypeReference<TexaporkerControl>() {};

  @Inject
  private TexapokerMgr texapokerMgr;
  @Inject
  private PlayerPrizePoolMgrScript playerPrizePoolMgr;
  @Inject
  private RoomPrizePoolMgrScript roomPrizePoolMgr;

  /**
   * 控制玩家发牌->玩家和机器人玩才控制.
   * 
   * @param table .
   */
  public void controlDealCards(TexapokerRoom.Table table) {
    boolean isHaveRot = false;
    boolean isrealPlayer = false;
    for (TexapokerRoom.Table.Seat seat1 : table.seats) {
      if (seat1.getPlayerId() > 0) {
        if (!seat1.isRobot()) {
          isrealPlayer = true;
        }
        if (seat1.isRobot()) {
          isHaveRot = true;
        }
      }
    }
    /*
     * 玩家和机器人玩且有个人奖池 . ->个人策略 ->既有玩家又有机器人 ->有玩家被个人奖池控制就走个人控制，没有的就走房间控制
     */
    Map<Integer, Integer> orderPower = Maps.newConcurrentMap();
    List<Integer> winList = Lists.newArrayList();
    List<Integer> loserList = Lists.newArrayList();
    List<Integer> robotList = Lists.newArrayList();
    /**
     * key: . order, value: power
     */
    if (isHaveRot == true && isrealPlayer == true) {
      // 玩家个人奖池
      List<Integer> winner = Lists.newArrayList();
      List<Integer> loser = Lists.newArrayList();
      List<Integer> robot = Lists.newArrayList();

      for (TexapokerRoom.Table.Seat seat1 : table.seats) {
        if (seat1.getPlayerId() == 0) {
          continue;
        }
        if (seat1.isRobot()) {
          robot.add(seat1.getOrder());
          continue;
        }
        // ->存在个人控制，进入个人控制，没有的进入房间控制
        PlayerPrizePool seatPrizePool =
            playerPrizePoolMgr.prizePool(seat1.getPlayerId(), Game.TEXAPOKER);
        if (seatPrizePool != null) {
          if (seatPrizePool.getPrize().get() != 0) {
            TexaporkerControl pokerControl =
                seatPrizePool.control(TEXAPOKER_CONTROL_TYPE_REFERENCE);
            if (pokerControl != null) {
              boolean win = RandCodeUtil
                  .random(pokerControl.getLoseRatio() + pokerControl.getWinRatio()) >= pokerControl
                      .getLoseRatio();
              if (win) {
                winner.add(seat1.getOrder());
              } else {
                loser.add(seat1.getOrder());
              }
            }
          } else {
            roomPrizeControl(seat1, winner, loser);
          }
        } else {
          roomPrizeControl(seat1, winner, loser);
        }
      }

      winList.addAll(winner);
      loserList.addAll(loser);
      robotList.addAll(robot);
      int maxPower = winList.size() + loser.size() + robotList.size() - 1;
      if (winList.size() > 0) {
        for (Integer winOrder : winList) {
          int index = RandCodeUtil.random(0, winner.size() - 1);
          int order = winner.get(index);
          if (winOrder == order) {
            winner.remove(index);
            orderPower.put(order, maxPower);
            maxPower--;
          }
        }
      }

      if (robotList.size() > 0) {
        for (Integer robotOrder : robotList) {
          int index = RandCodeUtil.random(0, robot.size() - 1);
          int order = robot.get(index);
          if (robotOrder == order) {
            robot.remove(index);
            orderPower.put(order, maxPower);
            maxPower--;
          }
        }
      }
      if (loserList.size() > 0) {
        for (Integer loserOrder : loserList) {
          int index = RandCodeUtil.random(0, loser.size() - 1);
          int order = loser.get(index);
          if (loserOrder == order) {
            loser.remove(index);
            orderPower.put(order, maxPower);
            maxPower--;
          }
        }
      }

    }
    Collections.shuffle(winList);
    Collections.shuffle(robotList);
    Collections.shuffle(loserList);
    // 发牌
    texapokerMgr.dealCards(table, orderPower, winList, robotList, loserList);
  }

  /**
   * 房间控制 .
   *
   * @param seat 座位信息.
   * @param winner .
   * @param loser .
   */
  private void roomPrizeControl(TexapokerRoom.Table.Seat seat, List<Integer> winner,
      List<Integer> loser) {
    long seatChipsGold =
        texapokerMgr.convertGold(seat.table.room.getId().intValue(), seat.getTotalChips());
    seat.tempTotal = seatChipsGold;
    RoomPrizePool seatRoomPrizePool =
        roomPrizePoolMgr.roomPrizePool(seat.getPlayerId(), Game.TEXAPOKER, seat.table.room.getId());
    if (seatRoomPrizePool != null) {
      ControlStrategy strategy = seatRoomPrizePool.abledControlStrategy();
      if (strategy != null) {
        TexaporkerControl pokerControl = strategy.control(TEXAPOKER_CONTROL_TYPE_REFERENCE);
        if (pokerControl != null) {
          boolean win = RandCodeUtil
              .random(pokerControl.getLoseRatio() + pokerControl.getWinRatio()) >= pokerControl
                  .getLoseRatio();
          if (win) {
            winner.add(seat.getOrder());
          } else {
            loser.add(seat.getOrder());
          }
        } else {
          if (RandCodeUtil.randomBoolean()) {
            winner.add(seat.getOrder());
          } else {
            loser.add(seat.getOrder());
          }
        }
      } else {
        if (RandCodeUtil.randomBoolean()) {
          winner.add(seat.getOrder());
        } else {
          loser.add(seat.getOrder());
        }
      }
    } else {
      if (RandCodeUtil.randomBoolean()) {
        winner.add(seat.getOrder());
      } else {
        loser.add(seat.getOrder());
      }
    }
  }

  /**
   * 结算修改个人或房间奖池 .
   *
   * @param table .
   */
  public void banlanceControl(TexapokerRoom.Table table) {
    for (TexapokerRoom.Table.Seat seat : table.seats) { // 个人奖池
      if (seat.getPlayerId() == 0) {
        continue;
      }
      if (seat.isRobot()) {
        continue;
      }
      PlayerPrizePool playerPrizePools =
          playerPrizePoolMgr.prizePool(seat.getPlayerId(), Game.TEXAPOKER);
      if (playerPrizePools != null) {
        if (playerPrizePools.getPrize().get() != 0) {
          long totalGold =
              texapokerMgr.convertGold(table.room.getId().intValue(), seat.billBet - seat.tempbet);
          long prize = playerPrizePools.getPrize().get();
          if (prize > 0) {
            prize = prize - totalGold;
            prize = prize < 0 ? 0 : prize;
          } else if (prize < 0) {
            prize = prize - totalGold;
            prize = prize > 0 ? 0 : prize;
          }
          playerPrizePools.getPrize().getAndSet(prize);
          continue;
        }
      }
      RoomPrizePool seatRoomPrizePool =
          roomPrizePoolMgr.roomPrizePool(seat.getPlayerId(), Game.TEXAPOKER, table.room.getId());
      if (seatRoomPrizePool != null) {
        long totalGold =
            texapokerMgr.convertGold(table.room.getId().intValue(), seat.billBet - seat.tempbet);
        long prize = seatRoomPrizePool.getPrize().get();
        prize -= totalGold;
        seatRoomPrizePool.getPrize().getAndSet(prize);
      }
    }

  }
}
